#import "XfspeechPlugin.h"
#import "FlutterXfspeechPluginStream.h"
#import "IFlyMSC/IFlyMSC.h"
#import <QuartzCore/QuartzCore.h>
#import "ISRDataHelper.h"


@implementation XfspeechPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  FlutterMethodChannel* channel = [FlutterMethodChannel
      methodChannelWithName:@"flutter_xfspeech_plugin"
            binaryMessenger:[registrar messenger]];
  XfspeechPlugin* instance = [[XfspeechPlugin alloc] init];
  [registrar addMethodCallDelegate:instance channel:channel];
    
    FlutterEventChannel *eventChanel = [FlutterEventChannel eventChannelWithName:@"flutter_xfspeech_plugin_stream" binaryMessenger:[registrar messenger]];
     [eventChanel setStreamHandler:[[FlutterXfspeechPluginStream sharedInstance] streamHandler]];
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
  if ([@"getPlatformVersion" isEqualToString:call.method]) {
    result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
  }else if ([@"init" isEqualToString:call.method]){
      [self init : call.arguments];
  }else if ([@"startIvw" isEqualToString:call.method]){
      [self startIvw : call.arguments];
  }else if ([@"ivwStop" isEqualToString:call.method]){
      [self.iflyVoiceWakeuper stopListening];
      result(@"true");
  }else if ([@"startIat" isEqualToString:call.method]) {
      [self startIat];
      result(NULL);
  } else if ([@"iatStop" isEqualToString:call.method]) {
      [self iatStop];
      result(NULL);
  }else if ([@"cancel" isEqualToString:call.method]) {
      [self cancel];
      result(NULL);
  }
    
  else {
    result(FlutterMethodNotImplemented);
  }
}

- (void) init:(NSDictionary*) args {
    NSLog(@"执行了init 方法");
    NSString *appId = args[@"APP_ID"];
    NSString *initString = [[NSString alloc] initWithFormat:@"appid=%@", appId];
    [IFlySpeechUtility createUtility:initString];
}

- (void)startIat {
    if(_iFlySpeechRecognizer == nil)
    {
        [self initRecognizer];
    }
    
    [_iFlySpeechRecognizer cancel];
    
    //Set microphone as audio source
    [_iFlySpeechRecognizer setParameter:IFLY_AUDIO_SOURCE_MIC forKey:@"audio_source"];
    
    //Set result type
    [_iFlySpeechRecognizer setParameter:@"json" forKey:[IFlySpeechConstant RESULT_TYPE]];
    
    //Set the audio name of saved recording file while is generated in the local storage path of SDK,by default in library/cache.
    [_iFlySpeechRecognizer setParameter:@"asr.pcm" forKey:[IFlySpeechConstant ASR_AUDIO_PATH]];
    
    [_iFlySpeechRecognizer setDelegate:self];
    BOOL ret = [_iFlySpeechRecognizer startListening];
}

- (void)iatStop {
    [_iFlySpeechRecognizer stopListening];
}

- (void) startIvw:(NSDictionary*) args {
    NSString *appId = args[@"APP_ID"];
    NSLog(@"执行了startIvw 方法");
    
    //获取唤醒单例对象
    self.iflyVoiceWakeuper = [IFlyVoiceWakeuper sharedInstance];
    //设置唤醒协议委托
    self.iflyVoiceWakeuper.delegate = self;
    //设置唤醒参数
    //生成唤醒资源路径并设置唤醒资源，唤醒资源需要定制，与唤醒词一一对应。
    NSString *resPath = [[NSBundle mainBundle] resourcePath];
    NSString *wordPath = [[NSString alloc] initWithFormat:@"%@/%@.jet",resPath,appId];
    NSString *ivwResourcePath = [IFlyResourceUtil generateResourcePath:wordPath];
    [_iflyVoiceWakeuper setParameter:ivwResourcePath forKey:@"ivw_res_path"];
    //设置唤醒门限值,新唤醒引擎的默认门限制值为1450
    //门限设置要和资源中的唤醒词个数匹配，以;分割。
    //例如：0:1450，0代表第一个唤醒词 1450，代表第一个唤醒词门限
    //根据下载的SDK中的说明来设置。
    //0：表示第一个唤醒词，1450表示唤醒词对应的门限值；
    //1：表示第二个唤醒词，1450表示唤醒词对应的门限值
    [_iflyVoiceWakeuper setParameter:@"0:1450;1:1450;" forKey:@"ivw_threshold"];

    //设置唤醒的服务类型，目前仅支持wakeup
    [_iflyVoiceWakeuper setParameter:@"wakeup" forKey:@"ivw_sst"];
    //设置唤醒的工作模式
    //keep_alive表示一次唤醒成功后是否继续录音等待唤醒。1：表示继续；0：表示唤醒终止
    [_iflyVoiceWakeuper setParameter:@"1" forKey:@"keep_alive"];
    //启动唤醒
    int bRet = [self.iflyVoiceWakeuper startListening];
}


- (void)cancel {
    [[IFlySpeechRecognizer sharedInstance] cancel];
}

/**
 initialize recognition conctol and set recognition params
 **/
-(void)initRecognizer
{
    NSLog(@"%s",__func__);
        //recognition singleton without view
        if (_iFlySpeechRecognizer == nil) {
            _iFlySpeechRecognizer = [IFlySpeechRecognizer sharedInstance];
        }
            
        [_iFlySpeechRecognizer setParameter:@"" forKey:[IFlySpeechConstant PARAMS]];
            
        //set recognition domain
        [_iFlySpeechRecognizer setParameter:@"iat" forKey:[IFlySpeechConstant IFLY_DOMAIN]];
        
        _iFlySpeechRecognizer.delegate = self;
        
        if (_iFlySpeechRecognizer != nil) {
            //set timeout of recording
            [_iFlySpeechRecognizer setParameter:@"30000" forKey:[IFlySpeechConstant SPEECH_TIMEOUT]];
            //set VAD timeout of end of speech(EOS)
            [_iFlySpeechRecognizer setParameter:@"2000" forKey:[IFlySpeechConstant VAD_EOS]];
            //set VAD timeout of beginning of speech(BOS)
            [_iFlySpeechRecognizer setParameter:@"4000" forKey:[IFlySpeechConstant VAD_BOS]];
            //set network timeout
            [_iFlySpeechRecognizer setParameter:@"20000" forKey:[IFlySpeechConstant NET_TIMEOUT]];
        }
        
        //Initialize recorder
        if (_pcmRecorder == nil)
        {
            _pcmRecorder = [IFlyPcmRecorder sharedInstance];
        }
        
        _pcmRecorder.delegate = self;
        
        [_pcmRecorder setSaveAudioPath:nil];    //not save the audio file

}
#pragma mark - IFlySpeechRecognizerDelegate


/**
 volume callback,range from 0 to 30.
 **/
- (void) onVolumeChanged: (int)volume
{
    NSString * vol = [NSString stringWithFormat:@"%@：%d", NSLocalizedString(@"T_RecVol", nil),volume];
//    NSLog(@"vol=%@", vol);
}



/**
 Beginning Of Speech
 **/
- (void) onBeginOfSpeech
{
    NSLog(@"onBeginOfSpeech");
}

/**
 End Of Speech
 **/
- (void) onEndOfSpeech
{
    NSLog(@"onEndOfSpeech");
    [_pcmRecorder stop];
}

- (void) onResults:(NSArray *) results isLast:(BOOL)isLast
{
    NSMutableString *resultString = [[NSMutableString alloc] init];
    NSDictionary *dic = results[0];
    
    for (NSString *key in dic) {
        [resultString appendFormat:@"%@",key];
    }
    NSString * resultFromJson =  nil;
    resultFromJson = [ISRDataHelper stringFromJson:resultString];
    if(![resultFromJson isEqual: @""] && ![resultFromJson isEqual: @"。"]){
        
        NSData *data =[NSJSONSerialization dataWithJSONObject:dic options:kNilOptions error:nil];
        NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        
        NSMutableDictionary *resdic = [NSMutableDictionary dictionaryWithCapacity:1];
        [resdic setObject: [NSNumber numberWithBool:YES] forKey:@"success"];
        [resdic setObject:str forKey:@"result"];
        [resdic setObject:resultFromJson forKey:@"transResult"];
        [resdic setObject:@"2" forKey:@"type"];
        [[FlutterXfspeechPluginStream sharedInstance] streamHandler].eventSink(resdic);
    }
    NSLog(@"resultFromJson=%@",resultFromJson);
}

#pragma mark - IFlyVoiceWakeuperDelegate

/**
 result callback of voice wakeup
 resultDic：voice wakeup results
 **/
-(void) onResult:(NSMutableDictionary *)resultDic
{

    NSString *sst = [resultDic objectForKey:@"sst"];
    NSNumber *wakeId = [resultDic objectForKey:@"id"];
    NSString *score = [resultDic objectForKey:@"score"];
    NSString *bos = [resultDic objectForKey:@"bos"];
    NSString *eos = [resultDic objectForKey:@"eos"];
    NSString *keyword = [resultDic objectForKey:@"keyword"];
    
    NSLog(@"【KEYWORD】   %@",keyword);
    NSLog(@"【SST】   %@",sst);
    NSLog(@"【ID】    %@",wakeId);
    NSLog(@"【SCORE】 %@",score);
    NSLog(@"【EOS】   %@",eos);
    NSLog(@"【BOS】   %@",bos);
    
    NSLog(@"");
    NSMutableString *result = [[NSMutableString alloc] init];
    [result appendFormat:@"\n"];
    
    [result appendFormat:@"【KEYWORD】        %@\n",keyword];
    [result appendFormat:@"【SST】        %@\n",sst];
    [result appendFormat:@"【ID】         %@\n",wakeId];
    [result appendFormat:@"【SCORE】      %@\n",score];
    [result appendFormat:@"【EOS】        %@\n",eos];
    [result appendFormat:@"【BOS】        %@\n",bos];
    
    NSData *data =[NSJSONSerialization dataWithJSONObject:resultDic options:kNilOptions error:nil];
    NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    
    NSString * resultFromJson =  nil;
    //resultFromJson = [ISRDataHelper stringFromJson:result];
    resultFromJson = [NSString stringWithFormat:@"%@%@", @"",result];
    
    NSMutableDictionary *resdic = [NSMutableDictionary dictionaryWithCapacity:1];
    [resdic setObject: [NSNumber numberWithBool:YES] forKey:@"success"];
    [resdic setObject:str forKey:@"result"];
    [resdic setObject:resultFromJson forKey:@"transResult"];
    [resdic setObject:@"1" forKey:@"type"];
    [[FlutterXfspeechPluginStream sharedInstance] streamHandler].eventSink(resdic);

}

@end
